import {Callout, Tabs} from 'nextra/components';
import { Widget } from '@/components/demo/widget.tsx';
import LinkBadge from '@/components/ui/link-badge/link-badge.tsx';
import LinkBadgeGroup from '@/components/ui/link-badge/link-badge-group.tsx';

# Select Group

A group of items that allow users to make a selection from a set of options.

<LinkBadgeGroup>
    <LinkBadge label="API Reference" href="https://pub.dev/documentation/forui/latest/forui.widgets.select_group/"/>
</LinkBadgeGroup>

<Callout type="info">
    For touch devices, a [select tile group](/docs/tile/select-tile-group) or
    [select menu tile](/docs/tile/select-menu-tile) is generally recommended over this.
</Callout>

<Tabs items={['Preview', 'Code']}>
  <Tabs.Tab>
    <Widget name='select-group' variant='default' query={{}} height={300}/>
  </Tabs.Tab>
  <Tabs.Tab>
    ```dart copy
    enum Sidebar { recents, home, applications }

    FSelectGroup<Sidebar>(
      controller: FSelectGroupController(values: {Sidebar.recents}),
      label: const Text('Sidebar'),
      description: const Text('These will be shown in the sidebar.'),
      children: [
        .checkbox(
          value: Sidebar.recents,
          label: const Text('Recents'),
        ),
        .checkbox(
          value: Sidebar.home,
          label: const Text('Home'),
        ),
        .checkbox(
          value: Sidebar.applications,
          label: const Text('Applications'),
        ),
      ],
    );
    ```

  </Tabs.Tab>
</Tabs>

## CLI

To generate and customize this style:

```shell copy
dart run forui style create select-group
```

## Usage

### `FSelectGroup(...)`

```dart copy
FSelectGroup<Value>(
  controller: FSelectGroupController(), // or FSelectGroupController.radio()
  style: FSelectGroupStyle(...),
  label: const Text('Sidebar'),
  description: const Text('Select the items you want to display in the sidebar.'),
  onChange: (all) => print(all),
  onSelect: (selection) => print(selection),
  children: [
    .checkbox(
      value: Value.checkbox,
      label: const Text('Checkbox'),
    ),
    // or
    .radio(
      value: Value.radio,
      label: const Text('Radio'),
    ),
  ],
);
```

## Examples

### Checkbox Form

<Tabs items={['Preview', 'Code']}>
    <Tabs.Tab>
        <Widget name='select-group' variant='checkbox-form' query={{}} height={400}/>
    </Tabs.Tab>
    <Tabs.Tab>
        ```dart copy
        enum Language { dart, java, rust, python }

        class CheckboxForm extends StatefulWidget {
          const CheckboxForm({super.key});

          @override
          State<CheckboxForm> createState() => CheckboxFormState();
        }

        class CheckboxFormState extends State<CheckboxForm> {
          final _formKey = GlobalKey<FormState>();
          final controller = FSelectGroupController<Language>();

          @override
          Widget build(BuildContext context) => Form(
                key: _formKey,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    FSelectGroup(
                      controller: controller,
                      label: const Text('Favorite Languages'),
                      description: const Text('Your favorite language.'),
                      validator: (values) => values?.isEmpty ?? true ? 'Please select at least one language.' : null,
                      children: [
                        .checkbox(
                          value: Language.dart,
                          label: const Text('Dart'),
                        ),
                        .checkbox(
                          value: Language.java,
                          label: const Text('Java'),
                        ),
                        .checkbox(
                          value: Language.rust,
                          label: const Text('Rust'),
                        ),
                        .checkbox(
                          value: Language.python,
                          label: const Text('Python'),
                        ),
                      ],
                    ),
                    const SizedBox(height: 20),
                    FButton(
                      child: const Text('Submit'),
                      onPress: () {
                        if (!_formKey.currentState!.validate()) {
                          // Handle errors here.
                          return;
                        }

                        _formKey.currentState!.save();
                        // Do something.
                      },
                    ),
                  ],
                ),
              );

          @override
          void dispose() {
            controller.dispose();
            super.dispose();
          }
        }
        ```
    </Tabs.Tab>

</Tabs>

### Radio Form

<Tabs items={['Preview', 'Code']}>
  <Tabs.Tab>
    <Widget name='select-group' variant='radio-form' query={{}} height={400}/>
  </Tabs.Tab>
  <Tabs.Tab>
    ```dart copy
    enum Notification { all, direct, nothing }

    class RadioForm extends StatefulWidget {
      const RadioForm({super.key});

      @override
      State<RadioForm> createState() => RadioFormState();
    }

    class RadioFormState extends State<RadioForm> {
      final _formKey = GlobalKey<FormState>();
      final controller = FSelectGroupController<Notification>.radio();

      @override
      Widget build(BuildContext context) => Form(
            key: _formKey,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                FSelectGroup(
                  controller: controller,
                  label: const Text('Notifications'),
                  description: const Text('Select the notifications.'),
                  validator: (values) => values?.isEmpty ?? true ? 'Please select a value.' : null,
                  children: [
                    .radio(
                      value: Notification.all,
                      label: const Text('All new messages'),
                    ),
                    .radio(
                      value: Notification.direct,
                      label: const Text('Direct messages and mentions'),
                    ),
                    .radio(
                      value: Notification.nothing,
                      label: const Text('Nothing'),
                    ),
                  ],
                ),
                const SizedBox(height: 20),
                FButton(
                  child: const Text('Save'),
                  onPress: () {
                    if (!_formKey.currentState!.validate()) {
                      // Handle errors here.
                      return;
                    }

                    _formKey.currentState!.save();
                    // Do something.
                  },
                ),
              ],
            ),
          );

      @override
      void dispose() {
        controller.dispose();
        super.dispose();
      }
    }
    ```

  </Tabs.Tab>
</Tabs>
